package sn.layers;

import java.util.List;

import sn.Neuron;
import sn.functions.ActivationFunction;

public class OutputLayer extends Layer{
	
	public OutputLayer(int outputNeurons, ActivationFunction transferFunction) {
		super(outputNeurons, transferFunction);
	}
	
	public OutputLayer(List<Neuron> neurons){
		super(neurons);
	}

	@Override
	public void connect(Layer nextLayer, boolean initializeNeurons){
		throw new RuntimeException("Cannot connect to output layer.");
	}
	
	@Override
	public List<Double> compute(List<Double> intputs){
		List<Double> outputs = computeOutputs(intputs);
		return outputs;
	}

	public void train(List<Double> actual, List<Double> exact) {
		for(int thisLayer = 0; thisLayer < neurons.size(); thisLayer++){
			double element = 0.5*(exact.get(thisLayer)-actual.get(thisLayer))*(exact.get(thisLayer)-actual.get(thisLayer));
			neurons.get(thisLayer).increaseSigma(element);
		}
		train();
	}
	
	@Override
	public void updateWeights() {
		for(Neuron neuron : neurons){
			neuron.updateWeights();
		}
		System.out.println("Network trained successfully.");
	}
	
	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("Output: ").append(getNeuronCount()).append(" neurons.\n").append("Neurons:\n");
		for(Neuron n : neurons){
			sb.append(n.toString());
		}
		return sb.toString();
	}

}
